package cn.virens.common.mybatis.mapper;

import cn.virens.common.util.exception.APIException;
import io.mybatis.mapper.base.EntityMapper;
import io.mybatis.mapper.base.EntityProvider;
import io.mybatis.provider.Caching;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Lang;
import org.apache.ibatis.annotations.Options;
import org.dromara.hutool.core.collection.CollUtil;

import java.io.Serializable;
import java.util.Collection;

public interface BaseMapper<T> extends EntityMapper<T, Serializable> {
    /**
     * 保存实体，默认主键自增，并且名称为 id
     * <p>
     * 这个方法是个示例，你可以在自己的接口中使用相同的方式覆盖父接口中的配置
     *
     * @param entity 实体类
     * @return 1成功，0失败
     */
    @Override
    @Lang(Caching.class)
    @Options(useGeneratedKeys = true, keyProperty = "id")
    @InsertProvider(type = EntityProvider.class, method = "insert")
    <S extends T> int insert(S entity);

    /**
     * 保存实体中不为空的字段，默认主键自增，并且名称为 id
     * <p>
     * 这个方法是个示例，你可以在自己的接口中使用相同的方式覆盖父接口中的配置
     *
     * @param entity 实体类
     * @return 1成功，0失败
     */
    @Override
    @Lang(Caching.class)
    @Options(useGeneratedKeys = true, keyProperty = "id")
    @InsertProvider(type = EntityProvider.class, method = "insertSelective")
    <S extends T> int insertSelective(S entity);

    /**
     * 批量保存实体，需要数据库支持批量插入的语法
     *
     * @param records 实体列表
     * @return 返回插入失败的数据列表
     */
    default <S extends T> Collection<S> insertList(Collection<S> records) throws APIException {
        return CollUtil.filter(records, record -> insertSelective(record) > 0);
    }
}
